/*
 * open a pfkey socket or dump a reason why it failed.
 * Copyright (C) 2006 Michael Richardson <mcr@xelerance.com>
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Library General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
 * License for more details.
 *
 */
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include "openswan.h"
#include <openswan/pfkeyv2.h>

extern char *progname;

void pfkey_write_error(int writeerror, int err)
{
	fprintf(stderr, "%s: pfkey write failed, returning %d with errno=%d.\n",
		progname, writeerror, err);
	switch(err) {
	case EACCES:
		fprintf(stderr, "access denied.  ");
		if(getuid() == 0) {
			fprintf(stderr, "Check permissions.  Should be 600.\n");
		} else {
			fprintf(stderr, "You must be root to open this file.\n");
		}
		break;
#ifdef EUNATCH
	case EUNATCH:
		fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n");
		break;
#endif
	case EBUSY:
		fprintf(stderr, "KLIPS is busy.  Most likely a serious internal error occured in a previous command.  Please report as much detail as possible to development team.\n");
		break;
	case EINVAL:
		fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n");
		break;
	case ENODEV:
		fprintf(stderr, "KLIPS not loaded or enabled.\n");
		fprintf(stderr, "No device?!?\n");
		break;
	case ENOBUFS:
		fprintf(stderr, "No kernel memory to allocate SA.\n");
		break;
	case ESOCKTNOSUPPORT:
		fprintf(stderr, "Algorithm support not available in the kernel.  Please compile in support.\n");
		break;
	case EEXIST:
		fprintf(stderr, "SA already in use.  Delete old one first.\n");
		break;
	case ENOENT:
		fprintf(stderr, "device does not exist.  See FreeS/WAN installation procedure.\n");
		break;
	case ENXIO:
		fprintf(stderr, "SA does not exist.  Cannot delete.\n");
		break;
	case ENOSPC:
		fprintf(stderr, "no room in kernel SAref table.  Cannot process request.\n");
		break;
	case ESPIPE:
		fprintf(stderr, "kernel SAref table internal error.  Cannot process request.\n");
		break;
	default:
		fprintf(stderr, "Unknown socket write error %d.  Please report as much detail as possible to development team.\n", errno);
	}
	exit(1);
}

